package main

import (
	"fmt"
	"reflect"
	"strconv"
)

func main() {
	//函数的反射
	/*
		思路：函数也是看做接口变量类型
		step1: 函数 ——> 反射对象，Value
		step2: kind ——> func
		step3: Call()
	*/
	f1 := fun001
	value := reflect.ValueOf(f1)
	fmt.Printf("kind:%s, type:%s\n", value.Kind(), value.Type()) //kind:func, type:func()
	value2 := reflect.ValueOf(fun002)

	value3 := reflect.ValueOf(fun003)
	fmt.Printf("kind:%s, type:%s\n", value2.Kind(), value2.Type()) //kind:func, type:func(int, string)
	fmt.Printf("kind:%s, type:%s\n", value3.Kind(), value3.Type()) //kind:func, type:func(int, string) string

	//通过反射调用函数
	value.Call(nil)
	value2.Call([]reflect.Value{reflect.ValueOf(1000), reflect.ValueOf("喜羊羊")})
	resultValue := value3.Call([]reflect.Value{reflect.ValueOf(2000), reflect.ValueOf("灰太狼")})
	fmt.Printf("%T\n", resultValue)                                                //[]reflect.Value
	fmt.Println(len(resultValue))                                                  //1
	fmt.Printf("kind:%s, type:%s\n", resultValue[0].Kind(), resultValue[0].Type()) //kind:string, type:string

	s := resultValue[0].Interface().(string)
	fmt.Println(s)        //灰太狼2000
	fmt.Printf("%T\n", s) //string
}

func fun001() {
	fmt.Println("我是函数fun001()，无参的。。。")
}

func fun002(i int, s string) {
	fmt.Println("我是函数fun002()，有参的。。。", i, s)
}

func fun003(i int, s string) string {
	fmt.Println("我是函数fun003()，有参的，也有返回值。。。", i, s)
	return s + strconv.Itoa(i)
}
